---
layout : doc
title : Navigation Frames
permalink: docs\NavigationFrames.html
---

Navigation Frames are probably the most crucial component to Phoenix, and are really what makes Phoenix different to the other frameworks.

A Navigation Frame is basically a Content Control, which maintains a Journal of the Controller actions that each view was created from, and the state of each page. Unlike other rich client MVC frameworks, Phoenix decided that using navigation frames to control navigation would be more extensible and flexible that creating a navigation service, which takes care of navigation for the application.

Because navigation is a concern of the frame, it enables a lot of really interesting scenario's like nested navigation frames, which you can target from your viewmodels, and still have proper lifecycle management

## Nested Navigation frames
By fully supporting nested navigation frames, Phoenix allows views to host child views, which also support navigation. Lets have an example.

We have an awesome scanner app, with a navigation frame at the top level.
![6NavigationFrames1](/img\6NavigationFrames1.png)

Clicking scan document will do something like `Controller<ScanController>().Invoke(c=>c.ScanDocument());` 

This will take us to a second view, which has a nested navigation frame, the xaml may look something like:

    <TabControl>
        <TabItem Header="Scan Document">
            <NavigationFrame ControllerAction="ScanController.SelectDocumentScanType" />
        </TabItem>
    </TabControl>
    
![6NavigationFrames2](/img\6NavigationFrames2.png)

When that navigation frame loads, it will automatically execute the SelectDocumentScanType action, we now have a nice doubled way to nest views. Previously I have injected the ISubView, or ISubViewModel into my viewmodel, then used a content control and bound the content to that injected view. Different frameworks deal with it in different way, but most require taking an additional dependency in your viewmodel.

So now we click Document Feeder, which invokes some code which looks like this:

    Controller<ScanController>().Invoke(c=>ScanUsingDocumentFeeder());
    
This will return a new view, and cause a navigation. Notice that the navigation was in the child navigation frame, phoenix tracks the context of each view, and will invoke controller actions in the same frame they are contained in. If you want to target another you can use the `Context.ResolveFrame("frameName")` helper. 

![6NavigationFrames3](/img\6NavigationFrames3.png)

We now click cancel.. this calls NavigateBack() on the top level frame, because Phoenix understands nested frames, it knows that the child navigation frame belongs to a view which is now orphaned (Phoenix only navigates backwards, the scan document view is gone as far as we care).

So phoenix will call deactivate on the child navigation frame, causing the scan using document feeder options view to be deactivated.

The Child navigation frame will then be disposed, this will cause ALL viewmodels in that frames journal to be disposed, and released. 

The end result is all viewmodels as far down the stack as it goes gets properly notified of the disposal, and all lifecycle events are properly fired. You can also hook into the onclosing event, allowing any active nested view to cancel a window close event, similar to Caliburn micros TryClose event.

Now have a think about how in the past, this sort of behaviour would have made your life simpler! I can think of many occasions where this behaviour would have simplified my code A LOT!

## Partial Views

We have talked about navigation frames, a simpler version is the Partial view, which is a navigation frame, but has no journal. It can navigate and be targeted, but it does not maintain a back stack. It also can be nested and fully participates in the lifecycle and same behaviours as described above.

## Controller Action Context

In the viewmodel, we expose the ControllerActionContext, this has the NavigationFrame and Content frame exposed. 

Often NavigationFrame and ContentFrame will be the same, unless a partial view is hosting the current view, then the ContentFrame will be the partial view, and the NavigationFrame is the closest NavigationFrame to this view.

To navigate back, or manupulate the back stack, currently you access the journal of the Navigation frame with code which looks something like `Context.NavigationFrame.Journal.Pop();` This will likely get cleaned up and made more convienient before v1 is released.